/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.gt.web;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.constant.Constant;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
import com.thinkgem.jeesite.common.utils.CookieUtils;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;

/**
 * 导出Controller
 * @author zhangad
 * @version 2017-8-30
 */
@Controller
@RequestMapping(value = "${frontPath}/gt/exportDB")
public class ExportDBController extends BaseController {
	
	private static List<String> logList = new ArrayList<String>();
	
	/**
	 * 启动导出命令
	 */
	@ResponseBody
	@RequestMapping(value = "startExport")
	
	public String startExport(HttpServletRequest request, HttpServletResponse response) {
		response.setContentType("text/html; charset=utf-8"); 
		String spiderBatPath = Global.getConfig("export.bat.path");
		System.out.println(spiderBatPath);
		String exportLogPath = Global.getConfig("export.log.path");
		File logFile = new File(exportLogPath);
		PrintWriter pw = null;
		final Map<String,Object> rs = new HashMap<String,Object>();
		rs.put("success", false);
		// 每次请求，清空日志列表
		String startLine = "=========================导出开始:" + DateUtils.getDate("yyyy-MM-dd HH:mm:ss") + "==========================";
		
		// 记录日志
		request.setAttribute("title", "管理员：" + UserUtils.getUser().getLoginName() + "生成了数据库备份文件" + DateUtils.getDate("yyyy-MM-dd") + ".dmp");
		
		logList = new ArrayList<String>();
		logList.add(startLine);
		if(logFile.exists())
		{
			try {
				pw = new PrintWriter(new FileWriter(logFile),true);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}else
		{
			try {
				logFile.createNewFile();
				pw = new PrintWriter(new FileWriter(logFile),true);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		try {
			
            Process ps = Runtime.getRuntime().exec("cmd  /c " + spiderBatPath);
            InputStream in = ps.getErrorStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in,"gbk"));
            String line;
            pw.write(startLine);
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
                if(null != pw)
                {
                	pw.write(line + "\n");
                	pw.flush();
                	logList.add(line);
                }
            }
            String endLine = "=========================数据导出完毕，导出成功。 " + DateUtils.getDate("yyyy-MM-dd HH:mm:ss") + "==========================";
            pw.write(endLine);
            logList.add(endLine);
            in.close();
            pw.close();
            ps.waitFor();
            rs.put("success", true);
            rs.put("massage", "数据导出完毕，导出成功。");

        } catch (IOException ioe) {
            ioe.printStackTrace();
            rs.put("massage", "数据导出异常：" + ioe.getMessage());
        } catch (InterruptedException e) {
            e.printStackTrace();
            rs.put("massage", "数据导出异常：" + e.getMessage());
        }
        System.out.println("thread done");
		return JsonMapper.nonDefaultMapper().toJson(rs);
		
		
		
		
		/*try {
            final CountDownLatch threadSignal = new CountDownLatch(2);//初始化countDown  
              
            System.out.println("Start ......");  
            final Process pro = Runtime.getRuntime().exec("cmd  /c " + spiderBatPath);  
            pro.getOutputStream().close();  
            Runnable errThread = new Runnable() {
                @Override  
                public void run() {
                    try {  
                        InputStream is = pro.getErrorStream();  
                        InputStreamReader isr = new InputStreamReader(is);  
                        BufferedReader br = new BufferedReader(isr);  
                        String line = "";  
                        StringBuilder sb = new StringBuilder();  
                        while((line = br.readLine()) != null) {  
                            sb.append(line);
                            logList.add(line);
                        }  
                        System.out.println("error : " + sb.toString());  
                        is.close();  
                        isr.close();  
                        br.close();  
                        String endLine = "=========================数据导出完毕，导出成功。 " + DateUtils.getDate("yyyy-MM-dd HH:mm:ss") + "==========================";
                        logList.add(endLine);
                        rs.put("success", true);
                        rs.put("massage", "数据导出完毕，导出成功。");
                    } catch (IOException e) {
                    	rs.put("massage", "数据导出异常：" + e.getMessage());
                        e.printStackTrace();
                    }  
                      
                    threadSignal.countDown();//线程结束时计数器减1   
                }  
            };  
              
            new Thread(errThread).start();  
              
            Runnable inputThread = new Runnable() {  
                @Override  
                public void run() {
                    try {  
                        InputStream is = pro.getInputStream();  
                        InputStreamReader isr = new InputStreamReader(is);  
                        BufferedReader br = new BufferedReader(isr);  
                        String line = "";  
                        StringBuilder sb = new StringBuilder();  
                        while((line = br.readLine()) != null) {  
                            sb.append(line); 
                        	logList.add(line);
                        }  
                        System.out.println("input : " + sb.toString());  
                          
                        is.close();  
                        isr.close();  
                        br.close();  
                        // String endLine = "=========================数据导出完毕，导出成功。 " + DateUtils.getDate("yyyy-MM-dd HH:mm:ss") + "==========================";
                        // logList.add(endLine);
                        // rs.put("success", true);
                        // rs.put("massage", "数据导出完毕，导出成功。");
                    } catch (IOException e) {
                    	rs.put("massage", "数据导出异常：" + e.getMessage());
                        e.printStackTrace();  
                    }  
                      
                    threadSignal.countDown();//线程结束时计数器减1   
                }  
            };  
              
            new Thread(inputThread).start();  
            try {  
                threadSignal.await();  
            } catch (InterruptedException e) {
            	rs.put("massage", "数据导出异常：" + e.getMessage());
                e.printStackTrace();  
            }  
        } catch (IOException e) {
        	rs.put("massage", "数据导出异常：" + e.getMessage());
            e.printStackTrace();  
        }  
	
		return JsonMapper.nonDefaultMapper().toJson(rs);
	*/
	
	
	}
	
	/**
	 * 导出首页
	 */
	// @RequiresPermissions("cms:article:spider")
	@RequestMapping(value = {"exportDBIndex", ""})
	
	public String spiderIndex(String menuId, HttpServletRequest request, HttpServletResponse response) {
		
		request.setAttribute("menuId", menuId);
		
		List<String> dmpFiles = new ArrayList<String>();
		String dmpPath = Global.getDmpPath();
		if(StringUtils.isBlank(dmpPath))
		{
			dmpPath = "F:/app/Administrator/admin/orcl/dpdump";
		}
		File file = new File(dmpPath);
		if(file.isDirectory())
		{
			File []files = file.listFiles();
			if(null != files && files.length > 0)
			{
				for(File f:files)
				{
					if(f.getName().endsWith("DMP") || f.getName().endsWith("dmp"))
					{
						dmpFiles.add(f.getName());
					}
				}
			}
		}
		
		request.setAttribute("dmpFiles", dmpFiles);
		
		// return "modules/cms/spiderIndex";
		return "modules/gt/basic/exportDBIndex";
	}
	
	/**
     * 数据文件下载
     */
    @RequestMapping("downLoadDmp")
    public void downLoadDmp(String dmpName,String timeStamp,HttpServletRequest request, HttpServletResponse response) throws IOException{
    	 // String templatePath = request.getSession().getServletContext().getRealPath("/template");
	     // String path = templatePath+"/奖品信息导入模板.xlsx"; 
    	 // String path = templatePath+"/" + Global.getConfig("batchImportTemplate"); 
    	String dmpPath = Global.getDmpPath();
		if(StringUtils.isBlank(dmpPath))
		{
			dmpPath = "F:/app/Administrator/admin/orcl/dpdump";
		}
		dmpPath += "\\" + dmpName;
    	File file = new File(dmpPath);// path是根据日志路径和文件名拼接出来的
    	
    	request.setAttribute("title", "管理员：" + UserUtils.getUser().getLoginName() + "下载了数据备份文件" + dmpName + "。" + (file.exists()?"" : "但是文件不存在。"));
    	
    	if(file.exists()){
    		// String filename = file.getName();// 获取日志文件名称
            InputStream fis = new BufferedInputStream(new FileInputStream(dmpPath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(dmpName.replaceAll(" ", "").getBytes("utf-8"),"iso8859-1"));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream os = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            
            rememberCookieToken(timeStamp,"downToken",request,response);
            rememberCookieToken(String.valueOf(file.length()),"fileSize",request,response);
            
            os.write(buffer);// 输出文件
            String areaType = UserUtils.getUser().getArea().getType();
            
            // 还有省级及以上管理员下载后，备份文件才被删除
            if(Integer.parseInt(areaType) < Integer.parseInt(Constant.Area.AREA_TYPE_REGION))
            {
	            //导出完成后，删除文件
	            file.delete();
            }
            
            os.flush();
            os.close();
    	}else{
    		System.out.println("没有找到文件");
    		
    		rememberCookieToken(timeStamp,"downToken",request,response);
    		rememberCookieToken("null","fileSize",request,response);
    		
    	}
    
    }
	
	/**
	 * 导出日志
	 */
	//  @RequiresPermissions("cms:article:spider")
	@ResponseBody
	@RequestMapping(value = "exportLog")
	
	public String exportLog(int startLine,HttpServletRequest request, HttpServletResponse response) {
		response.setContentType("text/html; charset=utf-8");
		Map<String,Object> rs = new HashMap<String,Object>();
		rs.put("success", true);
		List<String> subLogList = new ArrayList<String>();
		if(startLine < 1)
		{
			subLogList = logList;
		}else
		{
			subLogList = logList.subList(startLine,logList.size());
		}
		
		if(null != subLogList && subLogList.size() > 0)
		{
			startLine += subLogList.size();
		}
		rs.put("startLine", startLine);
		
		rs.put("data", getListStr(subLogList));
		
		return JsonMapper.nonDefaultMapper().toJson(rs);
	}
	
	public String getListStr(List<String> subLogList)
	{
		
		if(null == subLogList || subLogList.size() < 1)
		{
			return "";
		}
		StringBuffer sb = new StringBuffer(1024);
		
		for(String line : subLogList)
		{
			line = line.trim();
			if(line.endsWith(".jar"))
			{
				continue;
			}
			sb.append(line).append("</br>");
		}
		
		return sb.toString();
	}
	
	// 导出时记录导出令牌，用于前台导出时，知道后台已导出完毕
	 public void rememberCookieToken(String timeStamp,String key, HttpServletRequest request, HttpServletResponse response)
	    {
	    	if(StringUtils.isNotBlank(timeStamp))
	    	{
	    		CookieUtils.setCookie(response, key, timeStamp, 3600);
	    		String cookie=request.getHeader("cookie");
	    		System.out.println(CookieUtils.getCookie(request, "downToken"));
	    		System.out.println(cookie);
	    	}
	    }
}
